using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Diagnostics;
using System.Text;
using System.Web.UI.WebControls;
using System.Xml;
using System.Xml.XPath;
using System.Reflection;

using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;
using Microsoft.SharePoint.Deployment;
using Microsoft.SharePoint.Utilities;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint.WebPartPages;

//using Microsoft.Office.Server;
using System.Globalization;
using System.ComponentModel;
using System.Web.UI;



namespace zevenseas.LifeCycleManagement.Utilities
{ 

    public class Utilities
    {
        public enum List
        {
            WebApplication,
            DeletedSitesList,
            UnusedSitesList,
            UnusedWebsList
        }

        public static DataTable WebApplicationDataTable
        {
            get
            {
                DataTable webApplicationsTable = new DataTable();
                webApplicationsTable.Columns.Add("WebAppGuid");
                webApplicationsTable.Columns.Add("WebAppName");
                webApplicationsTable.Columns.Add("ContentDatabase");
                webApplicationsTable.Columns.Add("Server");
                webApplicationsTable.Columns.Add("SiteCount");
                webApplicationsTable.Columns.Add("Diskspace");
                webApplicationsTable.Columns.Add("Date");
                webApplicationsTable.Columns.Add("TotalSiteCollections");
                webApplicationsTable.Columns.Add("TotalDiskSpaceRequired");
                webApplicationsTable.Columns.Add("TotalContentDatabases");

                return webApplicationsTable;
            }
        }

        public static void SetWebProperty(string propertyValue, string propertyName, SPPropertyBag siteWebProperties)
        {
            string propertyname = "LCM_" + propertyName;

            if (siteWebProperties[propertyname] == null)
            {
                siteWebProperties.Add(propertyname, propertyValue);
            }
            else
            {
                siteWebProperties[propertyname] = propertyValue;
            }
            siteWebProperties.Update();
        }

        public static string GetWebProperty(string propertyName, SPPropertyBag siteWebProperties)
        {
            string propertyname = "LCM_" + propertyName;
            string returnvalue;

            if (siteWebProperties[propertyname] == null)
            {
                returnvalue = "";
            }
            else
            {
                returnvalue = siteWebProperties[propertyname];
            }

            return returnvalue;
        }
      
        public static DateTime GetLastUsageDate(SPWeb web)
        {
            DateTime dLastAccessedDate = DateTime.MinValue;

            try
            {
                DataTable dtUsageData = web.GetUsageData(SPUsageReportType.url, SPUsagePeriodType.lastMonth);

                if (dtUsageData != null)
                {
                    // no lassAccessedDate
                    //error = @"In GetLastUsageDate. Error: There is no usage information for this site.";
                    //return -1;
                    DataRow[] rows = dtUsageData.Select("Page<>'owssvr.dll'");
                    if (rows.Length == 0)
                    {
                        // no lassAccessedDate
                        //error = @"In GetLastUsageDate. Error: There is no usage information for this site.";
                        // return -1;
                    }
                    else
                    {
                        for (int i = 0; i < rows.Length; i++)
                        {
                            DateTime tDate = Convert.ToDateTime(rows[i]["Most Recent Day"]);
                            // use the greatest
                            if (tDate > dLastAccessedDate)
                            {
                                dLastAccessedDate = tDate;
                            }
                        }
                    }
                }
            }
            catch (Exception exc)
            {
                //error = "Get lass accessed date error";
                //return 0;
            }
        

            return dLastAccessedDate;

        }

        public static SPListItem GetAssociatedListItem(string Url)
        {
            SPList unusedSitesList = SPContext.Current.Web.Webs["LCM"].Lists["UnusedSites"];
            SPListItem returnItem = null;

            SPQuery itemQuery = new SPQuery();
            itemQuery.Query = "<Where><Eq><FieldRef Name='Url' /><Value Type='Text'>"+ Url +" </Value></Eq></Where><OrderBy />";

            SPListItemCollection itemCollection = unusedSitesList.GetItems(itemQuery);

            foreach (SPListItem item in itemCollection)
            {
                returnItem = item;
                break;
            }

            return returnItem;
        }

        public static SPListItem GetAssociatedListItem(string Id, string ListName)
        {
            SPList unusedSitesList = SPContext.Current.Web.Webs["LCM"].Lists[ListName];
            SPListItem returnItem = null;

            returnItem = unusedSitesList.GetItemById(int.Parse(Id));

            //SPQuery itemQuery = new SPQuery();
            //itemQuery.Query = "<Where><Eq><FieldRef Name='Id' /><Value Type='Integer'>" + Id + " </Value></Eq></Where><OrderBy />";

            //SPListItemCollection itemCollection = unusedSitesList.GetItems(itemQuery);

            //foreach (SPListItem item in itemCollection)
            //{
            //    returnItem = item;
            //    break;
            //}

            return returnItem;
        }

        public static List<string> GetSiteOwners(SPSite site)
        {
            List<string> userEmailAddresses = new List<string>();

            userEmailAddresses.Add(site.Owner.Email);

            SPRoleDefinition roleDefinition = site.RootWeb.RoleDefinitions.GetByType(SPRoleType.Administrator);
            foreach (SPRoleAssignment roleAssignment in site.RootWeb.RoleAssignments)
            {
                if (roleAssignment.RoleDefinitionBindings.Contains(roleDefinition))
                {
                    // Pull out the principal                
                    SPPrincipal principal = roleAssignment.Member;
                    //  If it is a user then the permissions are set explicitly 
                    if (principal is SPUser)
                    {
                        SPUser user = (SPUser)principal;
                        if (!userEmailAddresses.Contains(user.Email))
                        {
                            userEmailAddresses.Add(user.Email);
                        }
                    }
                    // If it is a group then check for users within the group                
                    if (principal is SPGroup)
                    {
                        SPGroup group = (SPGroup)principal;
                        if (group.Users.Count > 0)
                        {
                            foreach (SPUser user in group.Users)
                            {

                                if (!userEmailAddresses.Contains(user.Email))
                                {
                                    userEmailAddresses.Add(user.Email);
                                }
                            }
                        }
                    }
                }
            }

            return userEmailAddresses;
        }


        public static List<string> GetSiteOwners(SPWeb web)
        {
            List<string> userEmailAddresses = new List<string>();

            if (web.HasUniqueRoleAssignments)
            {
                SPRoleDefinition roleDefinition = web.RoleDefinitions.GetByType(SPRoleType.Administrator);

                foreach (SPRoleAssignment roleAssignment in web.RoleAssignments)
                {
                    if (roleAssignment.RoleDefinitionBindings.Contains(roleDefinition))
                    {
                        // Pull out the principal                
                        SPPrincipal principal = roleAssignment.Member;
                        //  If it is a user then the permissions are set explicitly 
                        if (principal is SPUser)
                        {
                            SPUser user = (SPUser)principal;
                            if (!userEmailAddresses.Contains(user.Email))
                            {
                                userEmailAddresses.Add(user.Email);
                            }
                        }
                        // If it is a group then check for users within the group                
                        if (principal is SPGroup)
                        {
                            SPGroup group = (SPGroup)principal;
                            if (group.Users.Count > 0)
                            {
                                foreach (SPUser user in group.Users)
                                {

                                    if (!userEmailAddresses.Contains(user.Email))
                                    {
                                        userEmailAddresses.Add(user.Email);
                                    }
                                }
                            }
                        }
                    }
                }
            }

            else
            {
                using (SPWeb firstUniqueAncestorWeb = web.FirstUniqueAncestorWeb)
                {
                    userEmailAddresses = GetSiteOwners(firstUniqueAncestorWeb);                
                }                
            }

            return userEmailAddresses;
        }


        public static bool IsEmailConfigured()
        {
            bool emailIsConfigured = false;
            foreach (SPWebApplication webApplication in SPWebService.AdministrationService.WebApplications)
            {
                SPOutboundMailServiceInstance emailService = webApplication.OutboundMailServiceInstance;
                if (emailService != null)
                {
                    emailIsConfigured = true;
                }
            }
            return emailIsConfigured;
        }

        public static bool CheckIfUsageIsEnabled()
        {
            bool sharedServiceProviderEnabled = false;
            bool centralAdministrationEnabled= false;

            SPUsageSettings usageSettings = SPWebService.AdministrationService.UsageSettings;
            centralAdministrationEnabled = usageSettings.UsageProcessingEnabled;
            
            

            //ServerContext current = ServerContext.Default;
            
            
            //object sharedResourceProvider = current.GetType().GetProperty("SharedResourceProvider", AllBindings).GetValue(current, null);
            //Type configurationType = Type.GetType("Microsoft.SharePoint.Portal.Analytics.Configuration, Microsoft.SharePoint.Portal, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c");
            //MethodInfo methodinfo = configurationType.GetMethod("IsAnalyticsEnabledOnSrp");
            //object IsAnalyticsEnabledOnSrp = methodinfo.Invoke(null, new object[] { sharedResourceProvider });
            
            //sharedServiceProviderEnabled = (bool)IsAnalyticsEnabledOnSrp;

            //if (sharedServiceProviderEnabled && centralAdministrationEnabled)
            if (centralAdministrationEnabled)
            { return true; }
            else
            { return false; }
        }

        public static ListViewWebPart CreateListViewWebPart(SPList list)
        {
            ListViewWebPart listViewWebPart = new ListViewWebPart();            
            listViewWebPart.ListName = list.ID.ToString("B").ToUpper();
            listViewWebPart.ChromeType = System.Web.UI.WebControls.WebParts.PartChromeType.TitleOnly;
            listViewWebPart.ChromeState = System.Web.UI.WebControls.WebParts.PartChromeState.Normal;
            listViewWebPart.ViewGuid = list.Views[0].ID.ToString("B").ToUpper();

            return listViewWebPart;
        }

        public static void DisableToolbar(ListViewWebPart lv)
        {
            //Thanks Marcel de Vries for creating this method to disable the "Full Toolbar" on the ListViewWebPart

            //  Extract view 
            System.Reflection.PropertyInfo ViewProp = lv.GetType().GetProperty("View", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
            SPView spView = ViewProp.GetValue(lv, null) as SPView;

            string txt = spView.SchemaXml;

            System.Reflection.PropertyInfo NodeProp = spView.GetType().GetProperty("Node", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
            XmlNode node = NodeProp.GetValue(spView, null) as XmlNode;
            XmlNode tBarNode = node.SelectSingleNode("Toolbar");

            if (tBarNode != null)
            {
                XmlAttribute typeNode = tBarNode.Attributes["Type"];
                // make the contents empty so we realy remove the toolbar .....
                // otherwise you might get a different type of toolbar popup when we have a 
                // Migrated site from 2.0
                tBarNode.RemoveAll();
                // re-add the type attribute
                tBarNode.Attributes.Append(typeNode);
                // finally set the toolbar to not show....
                typeNode.Value = "None";
            }

            //This forces a refresh of the views internal xml or the node's cild nodes are not populated 
            spView.Update();
        }

        internal static BindingFlags AllBindings
        {
            get
            {
                return BindingFlags.CreateInstance |
                BindingFlags.FlattenHierarchy |
                BindingFlags.GetField |
                BindingFlags.GetProperty |
                BindingFlags.IgnoreCase |
                BindingFlags.Instance |
                BindingFlags.InvokeMethod |
                BindingFlags.NonPublic |
                BindingFlags.Public |
                BindingFlags.SetField |
                BindingFlags.SetProperty |
                BindingFlags.Static;
            }
        }

        public static bool CheckIfLCMExists()
        {
            bool siteExists = false;
            
            SPWebApplication webApplication = SPAdministrationWebApplication.Local;
            
            SPWeb web = webApplication.Sites[0].AllWebs["LCM"];
            using (web)
            {
                try
                {
                    if (web.Url.EndsWith("LCM"))
                    {
                        siteExists = true;
                    }
                }
                catch (Exception) { }
            }

            return siteExists;
        }

        public static bool DoesWebExist(SPWebApplication webApplication)
        {
            bool webExists = false;
            try
            {
                using (SPWeb lcmWeb = webApplication.Sites[0].RootWeb.Webs["LCM"])
                {
                    if (lcmWeb.Title == "Life Cycle Management Logging and Analytical Site")
                    {
                        webExists = true;
                    }
                }
            }
            catch (Exception)
            { }


            return webExists;
        }

        public static bool DoesListExist(SPWeb web, string listName)
        {
            bool listExists = false;

            try
            {
                SPList list = web.Lists[listName];
                if (list != null)
                {
                    listExists = true;
                }
            }
            catch (Exception) { }

            return listExists;
        }

        public static bool DoesFolderExist(SPList list, string folderName)
        {
            bool folderExists = false;
            SPFolder folder = null;

            try
            {
                folder = list.ParentWeb.GetFolder(list.RootFolder + "/" + folderName);
                
            }
            catch (Exception) { }

            if (folder != null)
            {
                if (folder.Exists)
                {
                    folderExists = true;
                }
                
            }
            return folderExists;
        }

        public static SPList CreateList(SPWeb web, string listName, string description, List listType)
        {
            Guid newListID = Guid.NewGuid(); ;
            SPList listToCreate = null;

            try
            {
                newListID = web.Lists.Add(listName, description, SPListTemplateType.GenericList);
            }
            catch (Exception error)
            {
                throw (error);
            }

            if (newListID != null)
            {
                listToCreate = web.Lists[newListID];

                listToCreate.EnableAttachments = false;
                listToCreate.EnableVersioning = false;
                listToCreate.OnQuickLaunch = true;

                switch (listType)
                {
                   
                    case List.WebApplication:
                        listToCreate.Fields.Add("WebAppGuid", SPFieldType.Text, false);
                        listToCreate.Fields.Add("WebAppName", SPFieldType.Text, false);
                        listToCreate.Fields.Add("ContentDatabase", SPFieldType.Text, false);
                        listToCreate.Fields.Add("SiteCount", SPFieldType.Integer, false);
                        listToCreate.Fields.Add("Diskspace", SPFieldType.Integer, false);
                        listToCreate.Fields.Add("TotalDiskSpaceRequired", SPFieldType.Integer, false);
                        listToCreate.Fields.Add("TotalSiteCollections", SPFieldType.Integer, false);
                        listToCreate.Fields.Add("TotalContentDatabases", SPFieldType.Integer, false);
                        listToCreate.Fields.Add("Date", SPFieldType.DateTime, false);

                        SPFieldDateTime dateField = (SPFieldDateTime)listToCreate.Fields["Date"];
                        dateField.DisplayFormat = SPDateTimeFieldFormatType.DateOnly;
                        dateField.Update();

                        listToCreate.Update();

                        SPView webApplicationView = listToCreate.DefaultView;
                        webApplicationView.ViewFields.Add("WebAppGuid");
                        webApplicationView.ViewFields.Add("WebAppName");
                        webApplicationView.ViewFields.Add("ContentDatabase");
                        webApplicationView.ViewFields.Add("SiteCount");
                        webApplicationView.ViewFields.Add("Diskspace");
                        webApplicationView.ViewFields.Add("TotalDiskSpaceRequired");
                        webApplicationView.ViewFields.Add("TotalSiteCollections");
                        webApplicationView.ViewFields.Add("TotalContentDatabases");
                        webApplicationView.Update();
                        break;
                                          
                    case List.DeletedSitesList:                        
                        listToCreate.Fields.Add("SiteCollection", SPFieldType.Boolean, false);
                        listToCreate.Fields.Add("Web", SPFieldType.Boolean, false);
                        listToCreate.Fields.Add("Url", SPFieldType.Text, false);
                        listToCreate.Fields.Add("Date", SPFieldType.DateTime, false);
                        listToCreate.Fields.Add("Size", SPFieldType.Text, false);
                        listToCreate.Fields.Add("FileName", SPFieldType.Text, false);
                        listToCreate.Fields.Add("FileLocation", SPFieldType.Text, false);
                        listToCreate.Fields.Add("WebApplication", SPFieldType.Text, false);
                        listToCreate.Update();

                        SPView deletedSitesView = listToCreate.DefaultView;
                        deletedSitesView.ViewFields.Add("WebApplication");
                        deletedSitesView.ViewFields.Add("SiteCollection");
                        deletedSitesView.ViewFields.Add("Web");
                        deletedSitesView.ViewFields.Add("Url");
                        deletedSitesView.ViewFields.Add("Date");
                        deletedSitesView.ViewFields.Add("Size");
                        deletedSitesView.ViewFields.Add("FileName");
                        deletedSitesView.ViewFields.Add("FileLocation");
                        deletedSitesView.Update();
                        break;

                    case List.UnusedSitesList:                       
                        listToCreate.Fields.Add("WebApplication", SPFieldType.Text, false);
                        listToCreate.Fields.Add("SiteCollection", SPFieldType.Text, false);
                        listToCreate.Fields.Add("SiteGuid", SPFieldType.Text, false);
                        listToCreate.Fields.Add("Status", SPFieldType.Choice, false);
                        listToCreate.Fields.Add("Web", SPFieldType.Integer, false);
                        listToCreate.Fields.Add("UnusedWebs", SPFieldType.Integer, false);
                        listToCreate.Fields.Add("Url", SPFieldType.Text, false);
                        listToCreate.Fields.Add("LastUsageDate", SPFieldType.DateTime, false);
                        listToCreate.Fields.Add("Size", SPFieldType.Text, false);
                        listToCreate.Fields.Add("OwnerEmailAddress", SPFieldType.Text, false);


                        SPFieldChoice statusField = (SPFieldChoice)listToCreate.Fields["Status"];
                        statusField.Choices.Add("Mail");
                        statusField.Choices.Add("Lock");
                        statusField.Choices.Add("Delete");

                        listToCreate.Fields.Add("Locked", SPFieldType.Boolean, false);
                        listToCreate.Fields.Add("LockedAt", SPFieldType.DateTime, false);
                        listToCreate.Fields.Add("Mailed", SPFieldType.Boolean, false);
                        listToCreate.Fields.Add("MailedAt", SPFieldType.DateTime, false);
                        listToCreate.Fields.Add("AmountOfMails", SPFieldType.DateTime, false);
                        listToCreate.Fields.Add("Deleted", SPFieldType.Boolean, false);
                        listToCreate.Fields.Add("DeletedAt", SPFieldType.DateTime, false);

                        listToCreate.Update();

                        SPView unusedListView = listToCreate.DefaultView;
                        unusedListView.ViewFields.Add("WebApplication");
                        unusedListView.ViewFields.Add("SiteCollection");
                        unusedListView.ViewFields.Add("Web");
                        unusedListView.ViewFields.Add("Url");
                        unusedListView.ViewFields.Add("Status");
                        unusedListView.ViewFields.Add("LastUsageDate");
                        unusedListView.ViewFields.Add("Size");
                        unusedListView.ViewFields.Add("OwnerEmailAddress");
                        unusedListView.ViewFields.Add("Locked");
                        unusedListView.ViewFields.Add("LockedAt");
                        unusedListView.ViewFields.Add("Mailed");
                        unusedListView.ViewFields.Add("MailedAt");
                        unusedListView.ViewFields.Add("AmountOfMails");
                        unusedListView.ViewFields.Add("Deleted");
                        unusedListView.ViewFields.Add("DeletedAt");

                        unusedListView.Update();
                        break;

                    case List.UnusedWebsList:
                        listToCreate.Fields.Add("WebGuid", SPFieldType.Text, false);
                        listToCreate.Fields.Add("Title", SPFieldType.Text, false);
                        listToCreate.Fields.Add("SiteGuid", SPFieldType.Text, false);
                        listToCreate.Fields.Add("Size", SPFieldType.Integer, false);
                        listToCreate.Fields.Add("Url", SPFieldType.Text, false);
                        listToCreate.Fields.Add("LastUsage", SPFieldType.DateTime, false);
                        listToCreate.Fields.Add("ItemVersions", SPFieldType.Integer, false);                        
                        listToCreate.Fields.Add("Mailed", SPFieldType.Boolean, false);
                        listToCreate.Fields.Add("MailedAt", SPFieldType.DateTime, false);                        
                        listToCreate.Fields.Add("Deleted", SPFieldType.Boolean, false);
                        listToCreate.Fields.Add("DeletedAt", SPFieldType.DateTime, false);
                        listToCreate.Fields.Add("OwnerEmailAddress", SPFieldType.Text, false);
                        listToCreate.Update();

                        SPView unusedWebsListView = listToCreate.DefaultView;
                        unusedWebsListView.ViewFields.Add("WebGuid");
                        unusedWebsListView.ViewFields.Add("Title");
                        unusedWebsListView.ViewFields.Add("SiteGuid");
                        unusedWebsListView.ViewFields.Add("Size");
                        unusedWebsListView.ViewFields.Add("Url");
                        unusedWebsListView.ViewFields.Add("OwnerEmailAddress");
                        unusedWebsListView.ViewFields.Add("LastUsage");
                        unusedWebsListView.ViewFields.Add("ItemVersions");
                        unusedWebsListView.ViewFields.Add("Mailed");
                        unusedWebsListView.ViewFields.Add("MailedAt");
                        unusedWebsListView.ViewFields.Add("Deleted");
                        unusedWebsListView.ViewFields.Add("DeletedAt");                        
                        unusedWebsListView.Update();                       
                        
                        break;
                }
            }

            return listToCreate;
        }

       
       
    }

    public class SPBoundDateTimeField : SPBoundField
    {
        private readonly CultureInfo _culture;
        private string _dateFormat = "d";

        public SPBoundDateTimeField()
        {
            SPRegionalSettings regionalSettings = SPContext.Current.Web.CurrentUser.RegionalSettings ??
                                                  SPContext.Current.Web.RegionalSettings;

            if (regionalSettings != null)
            {
                _culture = new CultureInfo((int)regionalSettings.LocaleId);
            }
            else
            {
                _culture = CultureInfo.CurrentUICulture;
            }
        }
        public string DateFormat
        {
            get { return _dateFormat; }
            set
            {
                if (string.IsNullOrEmpty(value)) throw new ArgumentNullException("value");
                _dateFormat = value;
            }
        }
        protected override void ChildControlDataBinding(Control childControl, object dataItem,
                                                   MemberDescriptor dataFieldPropertyDescriptor)
        {
            string value = GetPropertyValue(dataItem, dataFieldPropertyDescriptor.Name); Label label = (Label)childControl; DateTime date;
            if (DateTime.TryParse(value, out date))
            {
                label.Text = date.ToString(DateFormat, _culture);
            }
            else
            {
                label.Text = value;
            }
        }
        protected override Control GetChildControlInstance()
        {
            return new Label();
        }
    }

    public class SPBoundBooleanField : SPBoundField
    {
        protected override void ChildControlDataBinding(Control childControl, object dataItem,
                                                        MemberDescriptor dataFieldPropertyDescriptor)
        {
            PlaceHolder placeHolder = (PlaceHolder)childControl;
            string propertyValueAsHtml = GetPropertyValueAsHtml(dataItem, dataFieldPropertyDescriptor.Name);
            if (!string.IsNullOrEmpty(propertyValueAsHtml))
            {
                Label label = new Label();
                switch (propertyValueAsHtml)
                {
                    case "1": label.Text = "Yes"; break;
                    case "0": label.Text = "No";break;
                }
                              
                placeHolder.Controls.Add(label);
            }
        }
        protected override Control GetChildControlInstance()
        {
            return new PlaceHolder();
        }
    }
}


